/**
 * 
 * NOTICE -- YOU MUST LEAVE THIS NOTICE IN PLACE.  PER THE TERMS OF THE LICENSE BELOW, YOU MAY SUBLICENSE THIS SOFTWARE 
 * IN ANY WAY THAT DOES NOT CONFLICT WITH THIS LICENSE.
 *
 * Copyright (c) 2011, Paul Gribben <paul.gribben@gmail.com>
 *
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
 *
 * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
 * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the 
 *       documentation and/or other materials provided with the distribution.
 *	
 *	THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, 
 *	INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 
 *	DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
 *	SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
 *	WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
 *	OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 */
package org.softwise.rss2kindle;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.InputStreamReader;
import java.io.Reader;
import java.text.MessageFormat;
import java.util.Map;
import java.util.Properties;

import org.apache.commons.io.FileUtils;
import org.softwise.rss2kindle.impl.Rss2Html;

/**
 * Launcher for RSS to MOBI generator
 * 
 * @author paul
 * 
 */
public class RssGenerator {

	/**
	 * 
	 * 
	 * @param args
	 */
	public static void main(String[] args) {
		final String OPT_CONFIG_FILE = "-f";

		try {
			if (args == null || args.length < 2) {
				usage();
			}
			if (args.length == 3 && args[0].equals(OPT_CONFIG_FILE)) {
				String driveLabel = args[2];
				Properties config = new Properties();
				Reader cReader = new FileReader(args[1]);

				try {
					config.load(cReader);
					for (Map.Entry<Object, Object> entry : config.entrySet()) {
						// docName=RSSUrl
						// OR
						// docName=[nnn]RSSUrl
						// where 'nnn' is the max number of entries to be read
						// off.

						processFeed((String) entry.getValue(), (String) entry
								.getKey(), driveLabel);
					}
				} finally {
					cReader.close();
				}
			} else if (args.length == 3) {
				String rssUrl = args[0];
				String docName = args[1];
				String driveLabel = args[2];
				processFeed(rssUrl, docName, driveLabel);
			} else {
				usage();
			}

		} catch (Exception e) {
			System.err.println("Error: " + e.toString());
			System.exit(1);
		}

		System.exit(0);
	}

	/**
	 * Convert an RSS feed into a HTML document then use kindlegen to convert to
	 * MOBI file.
	 * 
	 * @param rssUrl
	 * @param docName
	 * @param driveLabel
	 * @throws Exception
	 */
	public static void processFeed(String rssUrl, String docName,
			String driveLabel) throws Exception {
		File cwd = new File(".");

		int maxArticles = Integer.MAX_VALUE;
		if (rssUrl.startsWith("[")) {
			int idxCloseBracket = rssUrl.indexOf(']');
			maxArticles = Integer
					.parseInt(rssUrl.substring(1, idxCloseBracket));
			rssUrl = rssUrl.substring(idxCloseBracket + 1);
		}

		if (maxArticles == Integer.MAX_VALUE) {
			System.out.println(MessageFormat.format("Generating document {0}",
					docName));
		} else {
			System.out.println(MessageFormat.format(
					"Generating document {0} with article limit {1}", docName,
					maxArticles));
		}

		Rss2Html converter = new Rss2Html();
		String htmlDoc = docName + ".html";
		converter.generate(rssUrl, htmlDoc, maxArticles);

		if (driveLabel != null) {
			if (!(new File(cwd, "kindlegen.exe").exists())) {
				throw new Exception(
						"kindlegen.exe executable must be present in current directory.");
			}

			String outFile = docName + ".prc";
			ProcessBuilder pb = new ProcessBuilder("kindlegen.exe", htmlDoc,
					"-o", outFile);
			pb.directory(cwd);
			Process kindleGen = pb.start();
			readOffOutput(kindleGen);
			int retCode = kindleGen.waitFor();
			System.out.println("kindlegen return code: " + retCode);
			File generatedFile = new File(cwd, outFile);

			if (generatedFile.exists()) {
				String targetDir = driveLabel + ":\\documents";
				FileUtils.copyFileToDirectory(generatedFile,
						new File(targetDir));
				System.out.println("Added document to kindle: " + outFile);
				// tidy up
				generatedFile.delete();
				new File(cwd, htmlDoc).delete();
			}
		}
	}

	private static void usage() {
		System.err
				.println("Format A: rss_url output_doc_name KindleDriveLabel");
		System.err
				.println("\tExample: http://feeds.bbci.co.uk/news/rss.xml bbcNews E");
		System.err.println();
		System.err
				.println("Format B: -f configPropertiesFile KindleDriveLabel");
		System.err
				.println("\tNote: property format is: output_doc_name=rss_url");
		System.err.println("\tExample: -f myConfigFile.properties E");
		throw new IllegalArgumentException();
	}

	private static void readOffOutput(Process kindleGen) throws Exception {
		final BufferedReader pread = new BufferedReader(new InputStreamReader(
				kindleGen.getInputStream()));
		Thread rt = new Thread(new Runnable() {
			@Override
			public void run() {
				String line;
				try {
					while ((line = pread.readLine()) != null) {
						line = line.trim();
						if (line.length() > 0) {
							System.out.println("kindlegen>>" + line);
						}
					}
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		});

		rt.start();
		rt.join();
	}

}
